﻿#region Using Statements
using System;
using System.Reflection;
using System.Windows.Forms;
using DirectZZT.Shared.Core;
using DirectZZT.Shared.World;
using System.IO;
using System.Collections.Generic;
using System.Linq;
#endregion

namespace DirectZZT.Forms
{
    /// <summary>
    /// Allows for quick changing of world (temporary).
    /// </summary>
    public partial class ManageWorldWindow : Form
    {
        #region Static fields

        /// <summary>
        /// Whether or not this window is opened.
        /// </summary>
        internal static bool IsOpen { get; private set; }

        #endregion

        #region Fields

        private Dictionary<string, string> _serializers;

        #endregion

        #region Properties

        /// <summary>
        /// Gets/sets the selected action.
        /// </summary>
        public Action SelectedAction { get; set; }
        /// <summary>
        /// Gets/sets the path to the world file.
        /// </summary>
        public string WorldPath { get; set; }
        /// <summary>
        /// Gets/sets the alias of the world serializer to use.
        /// </summary>
        public string WorldSerializer { get; set; }

        #endregion

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the OpenWorldWindow class.
        /// </summary>
        public ManageWorldWindow()
        {
            InitializeComponent();

            _serializers = new Dictionary<string, string>();

            ExportedType[] exports = TypeManager.Instance.GetExports(typeof(IWorldSerializer));
            foreach (var item in exports)
            {
                IWorldSerializer serializer = (IWorldSerializer)Activator.CreateInstance(item.Type);
                _serializers[serializer.Extension] = item.Attribute.Alias;
            }

            foreach (string fileName in Directory.GetFiles(Assembly.GetExecutingAssembly().GetWorkingDirectory(), "*.zzt", SearchOption.AllDirectories))
            {
                cboPath.Items.Add(fileName);
            }
            foreach (string fileName in Directory.GetFiles(Assembly.GetExecutingAssembly().GetWorkingDirectory(), "*.zml", SearchOption.AllDirectories))
            {
                cboPath.Items.Add(fileName);
            }
            if (cboPath.Items.Count > 0)
            {
                cboPath.SelectedIndex = 0;
            }
        }

        #endregion

        #region Methods

        /// <summary>
        /// Called when the dialog is shown.
        /// </summary>
        /// <param name="e"></param>
        protected override void OnShown(EventArgs e)
        {
            base.OnShown(e);
            IsOpen = true;
        }

        /// <summary>
        /// Called when the dialog is closed.
        /// </summary>
        /// <param name="e"></param>
        protected override void OnClosed(EventArgs e)
        {
            base.OnClosed(e);
            IsOpen = false;
        }

        private void btnBrowse_Click(object sender, EventArgs e)
        {
            OpenFileDialog dialog = new OpenFileDialog();
            dialog.InitialDirectory = Assembly.GetExecutingAssembly().GetWorkingDirectory();
            dialog.Filter = "Valid world files (*.*)|*.*";
            if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                cboPath.Text = dialog.FileName;
            }
        }

        private void btnOK_Click(object sender, EventArgs e)
        {
            this.SelectedAction = (ManageWorldWindow.Action)tabControl1.SelectedIndex;
            this.WorldPath = cboPath.Text;
            this.WorldSerializer = txtWorldType.Text;
        }

        private void cboPath_TextChanged(object sender, EventArgs e)
        {
            if (cboPath.Text.Contains("."))
            {
                string ext = Path.GetExtension(cboPath.Text);
                if (!string.IsNullOrWhiteSpace(ext))
                {
                    string key = ext.Remove(0, 1).ToLowerInvariant();
                    if (_serializers.ContainsKey(key))
                    {
                        string alias = _serializers[key];
                        txtWorldType.Text = alias;
                        btnOK.Enabled = true;
                        return;
                    }
                }
            }
            txtWorldType.Text = "(not recognized)";
            btnOK.Enabled = false;
        }

        #endregion

        #region Nested types

        /// <summary>
        /// The selected action.
        /// </summary>
        public enum Action
        {
            /// <summary>
            /// The "open" action was chosen.
            /// </summary>
            Open = 0,
            /// <summary>
            /// The "save" action was chosen.
            /// </summary>
            Save = 1,
            /// <summary>
            /// The "create" action was chosen.
            /// </summary>
            CreateNew = 2,
        }

        #endregion
    }
}
